﻿using System;
using System.Diagnostics;
using System.Security.Authentication;
using System.Windows.Forms;
using AuthenticationTool.Properties;
using LinqToTwitter;
using RestSharp;
using RestSharp.Authenticators;
using RestSharp.Contrib;
using SocialMediaIntegrationPack;

namespace AuthenticationTool
{
    public partial class PinAuthenticationForm : Form
    {
        public PinAuthenticationForm()
        {
            InitializeComponent();
        }

        private void AuthenticationForm_Load(object sender, EventArgs e)
        {
            AuthorizeButton.Focus();
        }

        private void AuthorizeButton_Click(object sender, EventArgs e)
        {
            AuthorizeButton.Enabled = false;

            TokenTextBox.Clear();
            SecretTextBox.Clear();

            if (rbTwitter.Checked)
            {
                Authentication.GetPinCode getPinCode = delegate(Form dialogueForm)
                                                           {
                                                               // This code is being executed after user authorizes, which begins with the call to auth.Authorize() below.
                                                               if (!(dialogueForm is PinForm)) return string.Empty;
                                                               DialogResult dialogResult =
                                                                   (dialogueForm as PinForm).ShowDialog();
                                                               return dialogResult == DialogResult.OK
                                                                          ? (dialogueForm as PinForm).PinCode
                                                                          : string.Empty;
                                                           };
                bool successfulAuthentication = false;
                var newDialogueForm = new PinForm(this);
                try
                {
                    var authorizer = Authentication.AuthenticateViaPin(getPinCode, newDialogueForm) as PinAuthorizer;

                    Authentication.Result authenticationResult =
                        (newDialogueForm.DialogResult == DialogResult.No ||
                         newDialogueForm.DialogResult == DialogResult.Cancel)
                            ? Authentication.Result.UserCancelled
                            : (authorizer == null && newDialogueForm.DialogResult == DialogResult.None)
                                  ? Authentication.Result.DestinationUnreachable
                                  : (authorizer == null || !authorizer.IsAuthorized
                                         ? Authentication.Result.Unauthorized
                                         : Authentication.Result.Successful);

                    if (authenticationResult != Authentication.Result.Successful)
                    {
                        switch (authenticationResult)
                        {
                            case Authentication.Result.Unauthorized:
                                throw new AuthenticationException();
                            case Authentication.Result.DestinationUnreachable:
                                throw new InternetConnectionException();
                        }

                        return;
                    }

                    successfulAuthentication = true;

                    TokenTextBox.Text = Authentication.Encrypt(authorizer.Credentials.OAuthToken);
                    SecretTextBox.Text = Authentication.Encrypt(authorizer.Credentials.AccessToken);

                    CopyTokenButton.Enabled = true;
                    CopySecretButton.Enabled = true;
                }
                catch (AuthenticationException)
                {
                    // suppress authentication exception
                    MessageBox.Show(this, Resources.Authorization_Error_Message, Resources.Authorization_Error);
                }
                catch (InternetConnectionException)
                {
                    // suppress internet connection exception
                    MessageBox.Show(this, Resources.NoConnection, Resources.Authorization_Error);
                }
                catch (Exception exception)
                {
                    // suppress any other exception with showing popup window
                    MessageBox.Show(this, exception.Message, Resources.ErrorTitle);
                }
                finally
                {
                    if (!successfulAuthentication)
                    {
                        AuthorizeButton.Enabled = true;
                    }
                }
            }
            else
            {
                CopyTokenButton.Enabled = false;
                CopySecretButton.Enabled = false;
                try
                {
                    const string consumerKey = "7bwtr5rzi7nLQGLkA35aA";
                    const string consumerSecret = "V9yIOwKqjQfOKn1dznvL8yFZ14RmYhw5OwF7YVrVQ";

                    string baseUrl = "https://www.yammer.com";
                    var client = new RestClient(baseUrl);
                    client.Authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret);
                    var request = new RestRequest("oauth/request_token", Method.POST);
                    var response = client.Execute(request);
                    var qs = HttpUtility.ParseQueryString(response.Content);
                    var oauth_token = qs["oauth_token"];
                    var oauth_token_secret = qs["oauth_token_secret"];

                    request = new RestRequest("oauth/authorize");
                    request.AddParameter("oauth_token", oauth_token);
                    string url = client.BuildUri(request).ToString();
                    Process.Start(url);

                    var pf = new PinForm(this);
                    pf.Text = "Enter Code";
                    pf.label1.Text = "Code:";
                    if (pf.ShowDialog() == DialogResult.OK)
                    {
                        string verifier = pf.PinCode;
                        request = new RestRequest("oauth/access_token", Method.POST);
                        client.Authenticator = OAuth1Authenticator.ForAccessToken(
                            consumerKey, consumerSecret, oauth_token, oauth_token_secret, verifier
                            );
                        response = client.Execute(request);

                        qs = HttpUtility.ParseQueryString(response.Content);
                        TokenTextBox.Text = qs["oauth_token"];
                        SecretTextBox.Text = qs["oauth_token_secret"];
                        CopyTokenButton.Enabled = true;
                        CopySecretButton.Enabled = true;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error");
                    AuthorizeButton.Enabled = true;
                }
            }
        }

        private void TokenTextBox_Enter(object sender, EventArgs e)
        {
            (sender as TextBox).SelectAll();
        }

        private void SecretTextBox_Enter(object sender, EventArgs e)
        {
            (sender as TextBox).SelectAll();
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void CopyTokenButton_Click(object sender, EventArgs e)
        {
            var data = new DataObject(DataFormats.Text, TokenTextBox.Text);
            Clipboard.SetDataObject(data);
        }

        private void CopySecretButton_Click(object sender, EventArgs e)
        {
            var data = new DataObject(DataFormats.Text, SecretTextBox.Text);
            Clipboard.SetDataObject(data);
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            pictureBox1.Image = rbTwitter.Checked ? Resources.ico_authorization_80x80 : Resources.YammerIconApp126x126;
            AuthorizeButton.Enabled = true;
        }
    }
}